/* 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * PodcastPanel.java
 *
 * Created on May 4, 2009, 8:42:05 AM
 */
package com.bff.slimserver.musicjukebox.ui;

import com.bff.slimserver.music.exceptions.PlaylistException;
import com.bff.slimserver.musicjukebox.lib.JukeboxProperties;
import com.bff.bjj.ui.component.BJJPanel;
import com.bff.bjj.ui.component.BJJButton;
import com.bff.slimserver.musicjukebox.ui.components.radio.RadioItemList;
import com.bff.slimserver.musicjukebox.ui.components.radio.RadioItemListCellRenderer;
import com.bff.slimserver.musicjukebox.ui.components.radio.RadioTree;
import com.bff.bjj.utils.Utils;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.Timer;
import org.bff.slimserver.SlimPlayer;
import org.bff.slimserver.SlimPlaylist;
import org.bff.slimserver.SlimRadioPlugin;
import org.bff.slimserver.exception.SlimException;
import org.bff.slimserver.exception.SlimNetworkException;
import org.bff.slimserver.musicobjects.radio.SlimAvailableRadio;
import org.bff.slimserver.musicobjects.radio.SlimRadioAudioDetails;
import org.bff.slimserver.musicobjects.radio.SlimRadioItem;

/**
 *
 * @author Bill
 */
public class RadioPanel extends javax.swing.JPanel {

    private SlimPlaylist playlist;
    private SlimPlayer player;
    private SlimRadioPlugin radioPlugin;
    private JukeboxProperties jp;
    private boolean loadingItems;
    private static List<SlimAvailableRadio> loadedList;
    private static List<SlimRadioItem> loadedItemList;

    /** Creates new form PodcastPanel */
    public RadioPanel() {
        jp = JukeboxProperties.getInstance();
        try {
            this.playlist = jp.getPlaylist();
            this.player = jp.getPlayer();
            this.radioPlugin = jp.getRadioPlugin();
        } catch (PlaylistException ex) {
            Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SlimException ex) {
            Logger.getLogger(SongListTablePanel.class.getName()).log(Level.SEVERE, null, ex);
        }

        initComponents();
        listRadios();

        loadProgressBar.setVisible(false);
        loadProgressItems.setVisible(false);


        jpSearch.setVisible(false);

        Timer timer = new Timer(1000, new TimerListener());
        timer.setInitialDelay(0);
        timer.start();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel11 = new BJJPanel();
        jPanel5 = new javax.swing.JPanel();
        jPanel2 = new BJJPanel();
        jPanel1 = new BJJPanel();
        loadProgressBar = new javax.swing.JProgressBar();
        jScrollPane1 = new javax.swing.JScrollPane();
        radioTree = new RadioTree();
        jPanel3 = new BJJPanel();
        btnRefresh = new javax.swing.JButton();
        jPanel9 = new BJJPanel();
        lblError = new javax.swing.JLabel();
        lblError.setVisible(false);
        jPanel6 = new BJJPanel();
        jPanel7 = new BJJPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        podcastItemList = new RadioItemList();
        loadProgressItems = new javax.swing.JProgressBar();
        jPanel8 = new BJJPanel();
        btnAddToPlaylist = new BJJButton();
        btnPlayNext = new BJJButton();
        btnClearAndPlay = new BJJButton();
        jpSearch = new BJJPanel();
        tfSearchCriteria = new javax.swing.JTextField();
        btnSearch = new javax.swing.JButton();

        setLayout(new java.awt.BorderLayout());

        jPanel11.setMinimumSize(new java.awt.Dimension(600, 125));
        jPanel11.setPreferredSize(new java.awt.Dimension(600, 424));
        jPanel11.setLayout(new java.awt.BorderLayout());

        jPanel5.setLayout(new java.awt.BorderLayout());

        jPanel2.setLayout(new java.awt.BorderLayout());

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Radios"));
        jPanel1.setLayout(new java.awt.BorderLayout());

        loadProgressBar.setIndeterminate(true);
        loadProgressBar.setString("Loading Radios");
        loadProgressBar.setStringPainted(true);
        jPanel1.add(loadProgressBar, java.awt.BorderLayout.SOUTH);

        radioTree.addTreeExpansionListener(new javax.swing.event.TreeExpansionListener() {
            public void treeCollapsed(javax.swing.event.TreeExpansionEvent evt) {
            }
            public void treeExpanded(javax.swing.event.TreeExpansionEvent evt) {
                radioTreeTreeExpanded(evt);
            }
        });
        radioTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
            public void valueChanged(javax.swing.event.TreeSelectionEvent evt) {
                radioTreeValueChanged(evt);
            }
        });
        jScrollPane1.setViewportView(radioTree);

        jPanel1.add(jScrollPane1, java.awt.BorderLayout.CENTER);

        jPanel2.add(jPanel1, java.awt.BorderLayout.CENTER);

        btnRefresh.setText("Refresh");
        btnRefresh.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRefreshActionPerformed(evt);
            }
        });
        jPanel3.add(btnRefresh);

        jPanel2.add(jPanel3, java.awt.BorderLayout.SOUTH);

        lblError.setFont(new java.awt.Font("Tahoma", 1, 12));
        lblError.setForeground(java.awt.Color.red);
        lblError.setText("Error");
        jPanel9.add(lblError);

        jPanel2.add(jPanel9, java.awt.BorderLayout.NORTH);

        jPanel5.add(jPanel2, java.awt.BorderLayout.CENTER);

        jPanel11.add(jPanel5, java.awt.BorderLayout.CENTER);

        add(jPanel11, java.awt.BorderLayout.CENTER);

        jPanel6.setMinimumSize(new java.awt.Dimension(500, 100));
        jPanel6.setPreferredSize(new java.awt.Dimension(500, 207));
        jPanel6.setLayout(new java.awt.BorderLayout());

        jPanel7.setBorder(javax.swing.BorderFactory.createTitledBorder("Radio Items"));
        jPanel7.setLayout(new java.awt.BorderLayout());

        podcastItemList.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                podcastItemListMouseClicked(evt);
            }
        });
        podcastItemList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                podcastItemListValueChanged(evt);
            }
        });
        jScrollPane2.setViewportView(podcastItemList);

        jPanel7.add(jScrollPane2, java.awt.BorderLayout.CENTER);

        loadProgressItems.setIndeterminate(true);
        loadProgressItems.setString("Loading Radio Items");
        loadProgressItems.setStringPainted(true);
        jPanel7.add(loadProgressItems, java.awt.BorderLayout.SOUTH);

        jPanel6.add(jPanel7, java.awt.BorderLayout.CENTER);

        btnAddToPlaylist.setText("Add to Playlist");
        btnAddToPlaylist.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAddToPlaylistActionPerformed(evt);
            }
        });
        jPanel8.add(btnAddToPlaylist);

        btnPlayNext.setText("Play Next");
        btnPlayNext.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnPlayNextActionPerformed(evt);
            }
        });
        jPanel8.add(btnPlayNext);

        btnClearAndPlay.setText("Clear and Play");
        btnClearAndPlay.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnClearAndPlayActionPerformed(evt);
            }
        });
        jPanel8.add(btnClearAndPlay);

        jPanel6.add(jPanel8, java.awt.BorderLayout.SOUTH);

        jpSearch.setBorder(javax.swing.BorderFactory.createTitledBorder("Search Criteria"));
        jpSearch.setLayout(new java.awt.BorderLayout());

        tfSearchCriteria.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyTyped(java.awt.event.KeyEvent evt) {
                tfSearchCriteriaKeyTyped(evt);
            }
        });
        jpSearch.add(tfSearchCriteria, java.awt.BorderLayout.CENTER);

        btnSearch.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
        btnSearch.setText("Search");
        btnSearch.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSearchActionPerformed(evt);
            }
        });
        jpSearch.add(btnSearch, java.awt.BorderLayout.EAST);

        jPanel6.add(jpSearch, java.awt.BorderLayout.NORTH);

        add(jPanel6, java.awt.BorderLayout.EAST);
    }// </editor-fold>//GEN-END:initComponents

    private void podcastItemListMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_podcastItemListMouseClicked
        if (evt.getClickCount() == 2) {
        } else {
            JList lstCust = (JList) evt.getSource();
            int currIndex = lstCust.locationToIndex(evt.getPoint());
            Object currData = lstCust.getSelectedValue();
            Rectangle itemBounds = lstCust.getCellBounds(currIndex, currIndex);
            Point currPoint = new Point(evt.getX(), evt.getY());
            Component readyComponent = ((RadioItemListCellRenderer) lstCust.getCellRenderer()).getListCellRendererComponent(lstCust,
                    currData, currIndex, true, true);
            readyComponent.setSize(itemBounds.width, itemBounds.height);
            Component pressedComponent = null;
            while (readyComponent != pressedComponent) {
                if (pressedComponent != null) {
                    readyComponent = pressedComponent;
                }
                pressedComponent = readyComponent.getComponentAt((int) (currPoint.getX() - itemBounds.getX()),
                        (int) (currPoint.getY() - itemBounds.getY()));

                if (pressedComponent == null) {
                    return;
                }
                currPoint.setLocation(currPoint.getX() - itemBounds.getX(), currPoint.getY() - itemBounds.getY());
                itemBounds = pressedComponent.getBounds();
            }

            if (pressedComponent instanceof JButton) {
                ((JButton) pressedComponent).doClick();
                //System.out.println("Pressed JButton with text " + ((JButton) pressedComponent).getText() + " in row " + currIndex + " of JList");
            }
        }
    }//GEN-LAST:event_podcastItemListMouseClicked

    private void btnAddToPlaylistActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAddToPlaylistActionPerformed
        this.setCursor(Utils.getHourglassCursor());
        try {
            for (SlimRadioAudioDetails item : getRadioItemList().getSelectedRadios()) {
                try {
                    getPlaylist().addPluginItem(item);
                } catch (SlimNetworkException ex) {
                    Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SlimException ex) {
                    Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }

        } finally {
            this.setCursor(Utils.getNormalCursor());
        }
}//GEN-LAST:event_btnAddToPlaylistActionPerformed

    private void btnPlayNextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnPlayNextActionPerformed
        this.setCursor(Utils.getHourglassCursor());
        try {
            for (SlimRadioAudioDetails item : getRadioItemList().getSelectedRadios()) {
                try {
                    getPlaylist().insertPluginItem(item);
                } catch (SlimNetworkException ex) {
                    Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SlimException ex) {
                    Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } finally {
            this.setCursor(Utils.getNormalCursor());
        }
}//GEN-LAST:event_btnPlayNextActionPerformed

    private void btnClearAndPlayActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnClearAndPlayActionPerformed
        this.setCursor(Utils.getHourglassCursor());
        try {
            for (SlimRadioAudioDetails item : getRadioItemList().getSelectedRadios()) {
                try {
                    getPlaylist().playPluginItem(item);
                } catch (SlimNetworkException ex) {
                    Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
                } catch (SlimException ex) {
                    Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        } finally {
            this.setCursor(Utils.getNormalCursor());
        }
}//GEN-LAST:event_btnClearAndPlayActionPerformed

    private void btnRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRefreshActionPerformed
        listRadios();
    }//GEN-LAST:event_btnRefreshActionPerformed

    private void radioTreeValueChanged(javax.swing.event.TreeSelectionEvent evt) {//GEN-FIRST:event_radioTreeValueChanged
        listItems();
    }//GEN-LAST:event_radioTreeValueChanged

    private void podcastItemListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_podcastItemListValueChanged
//
//        if (!loadingItems) {
//            loadDetails();
//        }
    }//GEN-LAST:event_podcastItemListValueChanged

    private void radioTreeTreeExpanded(javax.swing.event.TreeExpansionEvent evt) {//GEN-FIRST:event_radioTreeTreeExpanded
        //listItems();
    }//GEN-LAST:event_radioTreeTreeExpanded

    private void btnSearchActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSearchActionPerformed
        loadProgressItems.setVisible(true);
        radioTree.setEnabled(false);
        podcastItemList.setEnabled(false);

        List<SlimRadioAudioDetails> audioItems = new ArrayList<SlimRadioAudioDetails>();
        try {
            SlimAvailableRadio radio = (SlimAvailableRadio) getRadioTree().getSelectedRadio();
            radio.setSearchCriteria(tfSearchCriteria.getText().trim());

            jpSearch.setVisible(false);
            SlimRadioItem radioItem = getRadioPlugin().loadRadio(radio, getPlayer());

            boolean loaded = loadedList.contains(radio);

            if (!loaded) {
                getRadioPlugin().loadRadio(radioItem, radio.getCommand(), getPlayer());
                loadedList.add(radio);
            }

            for (SlimRadioItem item : radioItem.getRadioItems()) {
                if (item.isAudio()) {
                    audioItems.add(getRadioPlugin().getAudioDetails(item, player));
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            podcastItemList.setEnabled(true);
            radioTree.setEnabled(true);
            loadProgressItems.setVisible(false);
        }

        if (audioItems.size() < 1) {
            JOptionPane.showMessageDialog(Utils.getParentComponent(this), "No radios found.");
        } else {
            getRadioItemList().setRadioItems(audioItems);
        }
    }//GEN-LAST:event_btnSearchActionPerformed

    private void tfSearchCriteriaKeyTyped(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_tfSearchCriteriaKeyTyped
        if (tfSearchCriteria.getText().trim().length() > 0) {
            btnSearch.setEnabled(true);
        } else {
            btnSearch.setEnabled(false);
        }
    }//GEN-LAST:event_tfSearchCriteriaKeyTyped
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAddToPlaylist;
    private javax.swing.JButton btnClearAndPlay;
    private javax.swing.JButton btnPlayNext;
    private javax.swing.JButton btnRefresh;
    private javax.swing.JButton btnSearch;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel11;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPanel jPanel5;
    private javax.swing.JPanel jPanel6;
    private javax.swing.JPanel jPanel7;
    private javax.swing.JPanel jPanel8;
    private javax.swing.JPanel jPanel9;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JPanel jpSearch;
    private javax.swing.JLabel lblError;
    private javax.swing.JProgressBar loadProgressBar;
    private javax.swing.JProgressBar loadProgressItems;
    private javax.swing.JList podcastItemList;
    private javax.swing.JTree radioTree;
    private javax.swing.JTextField tfSearchCriteria;
    // End of variables declaration//GEN-END:variables

    private RadioTree getRadioTree() {
        return (RadioTree) radioTree;
    }

    private void listRadios() {
        loadedList = new ArrayList<SlimAvailableRadio>();
        loadedItemList = new ArrayList<SlimRadioItem>();

        new Thread(new Runnable() {

            @Override
            public void run() {
                loadProgressBar.setVisible(true);

                try {
                    try {
                        lblError.setVisible(false);
                        getRadioTree().listAll();
                    } catch (Exception e) {
                        lblError.setText("Could not get radio list");
                        lblError.setVisible(true);
                        e.printStackTrace();
                        //new ErrorDialog(Utils.getParentComponent(getRadioTree()), "Could not get radio list.", e, false, false);
                    }

                } finally {
                    loadProgressBar.setVisible(false);
                }

            }
        }).start();
    }

    /**
     * @return the playlist
     */
    public SlimPlaylist getPlaylist() {
        return playlist;
    }

    /**
     * @param playlist the playlist to set
     */
    public void setPlaylist(SlimPlaylist playlist) {
        this.playlist = playlist;
    }

    private RadioItemList getRadioItemList() {
        return (RadioItemList) podcastItemList;
    }

    /**
     * @return the podcaster
     */
    public SlimRadioPlugin getRadioPlugin() {
        return radioPlugin;
    }

    /**
     * @param podcaster the podcaster to set
     */
    public void setPodcaster(SlimRadioPlugin radioPlugin) {
        this.radioPlugin = radioPlugin;
    }

    /**
     * @return the player
     */
    public SlimPlayer getPlayer() {
        return player;
    }

    /**
     * @param player the player to set
     */
    public void setPlayer(SlimPlayer player) {
        this.player = player;
    }

    private void listItems() {
        loadProgressItems.setVisible(true);
        radioTree.setEnabled(false);
        podcastItemList.setEnabled(false);
        new Thread(new Runnable() {

            public void run() {
                try {
                    loadingItems = true;

                    if (getRadioTree().getSelectedRadio() != null) {
                        List<SlimRadioAudioDetails> audioItems = new ArrayList<SlimRadioAudioDetails>();

                        if (getRadioTree().getSelectedRadio() instanceof SlimRadioItem) {
                            SlimRadioItem radio = (SlimRadioItem) getRadioTree().getSelectedRadio();
                            boolean loaded = loadedItemList.contains(radio);

                            if (!loaded) {
                                getRadioPlugin().loadRadio(radio, radio.getCommand(), getPlayer());
                                loadedItemList.add(radio);
                            }

                            for (SlimRadioItem item : radio.getRadioItems()) {
                                if (item.isAudio()) {
                                    audioItems.add(getRadioPlugin().getAudioDetails(item, player));
                                }
                            }
                        }

                        if (getRadioTree().getSelectedRadio() instanceof SlimAvailableRadio) {
                            SlimAvailableRadio radio = (SlimAvailableRadio) getRadioTree().getSelectedRadio();

                            if (!radio.isSearch()) {
                                jpSearch.setVisible(false);
                                SlimRadioItem radioItem = getRadioPlugin().loadRadio(radio, getPlayer());

                                boolean loaded = loadedList.contains(radio);

                                if (!loaded) {
                                    getRadioPlugin().loadRadio(radioItem, radio.getCommand(), getPlayer());
                                    loadedList.add(radio);
                                }

                                for (SlimRadioItem item : radioItem.getRadioItems()) {
                                    if (item.isAudio()) {
                                        audioItems.add(getRadioPlugin().getAudioDetails(item, player));
                                    }
                                }
                            } else {
                                jpSearch.setVisible(true);
                            }
                        }
                        getRadioItemList().setRadioItems(audioItems);
                    }
                } catch (SlimException ex) {
                    Logger.getLogger(RadioPanel.class.getName()).log(Level.SEVERE, null, ex);
                } finally {
                    podcastItemList.setEnabled(true);
                    radioTree.setEnabled(true);
                    loadProgressItems.setVisible(false);
                    loadingItems = false;
                }
            }
        }).start();
    }

    private class TimerListener implements ActionListener {

        private Color bg;
        private Color fg;
        private boolean isForeground;

        public TimerListener() {
            bg = btnSearch.getBackground();
            fg = btnSearch.getForeground();
        }

        public void actionPerformed(ActionEvent e) {

            if (isForeground) {
                btnSearch.setForeground(bg);
                btnSearch.setBackground(fg);
            } else {
                btnSearch.setForeground(fg);
                btnSearch.setBackground(bg);
            }

            isForeground = !isForeground;
        }
    }
}
